import Parser = require('./../base/Parser');
import GCJ_CLASS_TYPE = require('./../../common/GCJ_CLASS_TYPE');
import DEFINE = require('./../../common/DEFINE');
import ParaContour=require('./../../common/graph/ParaContour');
import  OnePara=require('./../../common/graph/OnePara');
import  ParaChar=require('./../../common/graph/ParaChar');
import Point=require('./../../common/graph/Point');
import FColor=require('./../color/FColor');
import ObjBase=require('./ObjBase');
import PageInfo=require('./../../common/PageInfo');
import ImageObj=require('./ImageObj');
import TextObj=require('./TextObj');
import GraphObj=require('./GraphObj');
import SJGPage=require('./../cont/SJGPage');
import SJGReplaceItemBase=require('./../replace/SJGReplaceItemBase');
import SJGReplaceGroup = require('./../replace/SJGReplaceGroup');
import ObjRelativePosType=require('./../base/ObjRelativePosType');
import ObjPositionAlign=require('./../base/ObjPositionAlign');
import ObjPosition=require('./../base/ObjPosition');
import FontStyle=require('./apperance/item/FontStyle');
import TextHeadStyle=require('./apperance/item/TextHeadStyle');


var path=require('path');
var CommonUtil=require('../../../../common/util/CommonUtil');
class SJGSelectRect{public static CONTROL_LEFT=3;public static CONTROL_RIGHT=1};
var async  = require( 'async'); // 同步控制
var fs = require('fs')
var CONFIG=require('../../../../common/config');
var rpcFunc=require('./../../../routes/rpcSrv/rpcFunc.js');

export  = TextExtObj;

/**
 *
 * @author 
 *
 */
class TextExtObj extends ObjBase{
    
    /*
     * 文字类型
     */
    public static TEXT_TYPE_BODY=0;// 正文
    public static TEXT_TYPE_TITLE=1;// 小标题
    public tt: number=TextExtObj.TEXT_TYPE_BODY;
    
    /*
     * TEXT
     */
    public te: string="";
    
    /**
     * font-zoom,放大倍数:文字过小时，图片服务会显示偏差，需要先放大
     */
    public fz=1;
    
    
    /**
     * 文字属性
     */ 
    public style: FontStyle=new FontStyle();
    
    
    /**
     * 字轮廓
     */
    public pc=new ParaContour();
   
    
    /**
     * [待废弃]小标题。注意：不影响文字本身的尺寸
     */
    public title: ObjBase=null;
    
    /**
     * [待废弃]小标题的位置类型
     */ 
    public titlePos: ObjRelativePosType=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_5,ObjPositionAlign.ALIGN_POINT_7);
    
    /**
     * [待废弃]小标题的偏移
     */     
    public titleOffset: Point=new Point();
    
    /**
     * 抬头：例如图标。注意：不影响文字本身的尺寸
     */
    public head: ObjBase=null;

    /**
     * 抬头属性：例如类型、对齐方式、位置等属性
     */
    public headStyle: TextHeadStyle=null;

    
    /**
     * [待废弃]抬头的位置类型
     */ 
    public headPos: ObjRelativePosType=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_5,ObjPositionAlign.ALIGN_POINT_7);
    
    /**
     * [待废弃]抬头的偏移
    */
    public headOffset: Point=new Point();
 
    /**
     * [待废弃]抬头的归属：0无，1属于小标题，2属于正文，3输入小标题＋正文整体
     */ 
    public static HEAD_ALIGN_TO_NONE           =0;
    public static HEAD_ALIGN_TO_TITLE          =1;
    public static HEAD_ALIGN_TO_TEXT           =2;
    public static HEAD_ALIGN_TO_TITLE_AND_TEXT =3;
    public headAlignTo=TextExtObj.HEAD_ALIGN_TO_TEXT;

    // 文字真正起始位置
    public txtStPt: Point=new Point(0,0);

    
    public constructor(g?) {
        super(g);
        
        this.ct= GCJ_CLASS_TYPE.CLASS_TYPE_TextExtObj;
	}
	
    // 从json对象(注意不是json字符串)中解析
    // 参数：self,true表示只拷贝自身数据，而不拷贝子的数据
    public fromJson(jsonObj,versionId,self?) {
        super.fromJson(jsonObj,versionId,self);

        this.tt=jsonObj.tt||TextExtObj.TEXT_TYPE_BODY;
        this.te=jsonObj.te||''; // text
        this.fz=jsonObj.fz||1;
        if(jsonObj.hasOwnProperty("style")) {
            this.style.fromJson(jsonObj.style,versionId);
        }
        if(jsonObj.hasOwnProperty("pc")) {
            this.pc.fromJson(jsonObj.pc,versionId);
        }

        // 文字小标题
        if(jsonObj.hasOwnProperty("title")) {
            var one: ObjBase=<ObjBase> Parser.fromUnknownJson(jsonObj.title,versionId,this.getGlobalData());
            if(one) {
                this.title=one;
                one.parent=this;// 建立子对父的引用
            }else{
                this.title=null;
            }
        }
        if(jsonObj.hasOwnProperty("titlePos")) {
            this.titlePos.fromJson(jsonObj.titlePos,versionId);
        }

        if(jsonObj.hasOwnProperty("titleOffset")) {
            this.titleOffset.fromArray(jsonObj.titleOffset);
        }

        // 文字抬头
        if(jsonObj.hasOwnProperty("head")) {
            var one: ObjBase=<ObjBase> Parser.fromUnknownJson(jsonObj.head,versionId,this.getGlobalData());
            if(one) {
                this.head=one;
                one.parent=this;// 建立子对父的引用
            } else {
                this.head=null;
            }
        }
        if(jsonObj.hasOwnProperty("headPos")) {
            this.headPos.fromJson(jsonObj.headPos, versionId);
        }
        if(jsonObj.hasOwnProperty("headOffset")) {
            this.headOffset.fromArray(jsonObj.headOffset);
        }
        this.headAlignTo=jsonObj.headAlignTo;
        // 抬头属性
        if(jsonObj.hasOwnProperty("headStyle")) {
            this.headStyle=new TextHeadStyle(this.getGlobalData());
            this.headStyle.fromJson(jsonObj.headStyle, versionId);
        }
        if(jsonObj.hasOwnProperty("txtStPt")) {
            this.txtStPt.fromArray(jsonObj.txtStPt);
        }

        // 加载文档时
        if (this.getGlobalData().docStatus() == DEFINE.DOC_STATUS_LOADING) {
            this.getGlobalData().objManager().saveObject( this );
        }
    }
    // 最小化TextExt转换成Json:所有页root对象只保留TextExtObj(且只保留fz\te\style\color\id\pos几个属性)
    public toJsonOfMinTextExt(): string {
        // 去掉父json字符串的头尾
        var superJson =super.toJson(); // 需要导出文字的基本信息如h，不能使用toJsonOfMinTextExt
        superJson=superJson.substr(1,superJson.length-2);

        var ret ="{";
        ret+=superJson;


        // fz
        ret+=",";
        ret+="\"fz\":";
        ret+=this.fz;

        // te
        //ret+=",";
        //ret+="\"te\":\"";
        //ret+=this.te;
        //ret+="\"";
        ret+=',';
        ret+='"te":'+'"';
        ret+=this.te.replace(/"/g,'\\\"')+'"';// 处理引号引起的问题


        // style
        if(this.style) {
            ret+=",";
            ret+="\"style\":";
            ret+=this.style.toJson();
        }

        // head
        if(this.head) {
            ret+=',';
            ret+='"head":';
            ret+=this.head.toJson();
        }

        // headStyle
        if(this.headStyle) {
            ret+=',';
            ret+='"headStyle":';
            ret+=this.headStyle.toJson();
        }

        // txtStPt
        if(this.txtStPt) {
            ret+=',';
            ret+='"txtStPt":';
            ret+=this.txtStPt.toArray();
        }


        ret+="}";
        return ret;
    }
    // 转成json字符串
    public toJson(): string {
        // 去掉父json字符串的头尾
        var superJson = super.toJson();
        superJson = superJson.substr(1,superJson.length - 2);

        var ret = '{';
        ret += superJson;

        // tt
        ret+=',';
        ret+='"tt":';
        ret+=this.tt;

        // te
        ret+=',';
        ret+='"te":'+'"';
        ret+=this.te.replace(/"/g,'\\\"')+'"';// 处理引号引起的问题

        // fz
        ret+=',';
        ret+='"fz":';
        ret+=this.fz;


        // style
        if(this.style){
            ret+=',';
            ret+='"style":';
            ret+=this.style.toJson();
        }

        // pc
        if(this.pc) {
            ret+=',';
            ret+='"pc":';
            ret+=this.pc.toJson();
        }
        // title
        if(this.title) {
            ret+=',';
            ret+='"title":';
            ret+=this.title.toJson();
        }
        // titlePos
        if(this.titlePos) {
            ret+=',';
            ret+='"titlePos":';
            ret+=this.titlePos.toJson();
        }
        // titleOffset
        if(this.titleOffset) {
            ret+=',';
            ret+='"titleOffset":';
            ret+=this.titleOffset.toArray();
        }
        // head
        if(this.head) {
            ret+=',';
            ret+='"head":';
            ret+=this.head.toJson();
        }
        // headPos
        if(this.headPos) {
            ret+=',';
            ret+='"headPos":';
            ret+=this.headPos.toJson();
        }
        // headOffset
        if(this.headOffset) {
            ret+=',';
            ret+='"headOffset":';
            ret+=this.headOffset.toArray();
        }

        // headAlignTo
        ret+=',';
        ret+='"headAlignTo":';
        ret+=this.headAlignTo;

        // headStyle
        if(this.headStyle) {
            ret+=',';
            ret+='"headStyle":';
            ret+=this.headStyle.toJson();
        }

        // txtStPt
        if(this.txtStPt) {
            ret+=',';
            ret+='"txtStPt":';
            ret+=this.txtStPt.toArray();
        }


        ret += '}';

        return ret;
    }
    
    
    // 获取对象名称
    public getObjetName(): string {
        var objNm = "增强文字";
        
        if(this.tt==TextExtObj.TEXT_TYPE_TITLE) {
            objNm+="(小标题)";
        }else {
            objNm+="(正文)";
        }
        
        if(this.title) {
            objNm += " [带小标题]";
        }
        if(this.head){
            objNm+=" [带抬头]";
        }
        
        // 检索所选page中的replaces，不能从map3[]取
        var selPage: SJGPage=this.getGlobalData().selectManager().getPageOfSelect();
        var t=selPage.isTitleOrSubTitle(this.id);
        if(SJGReplaceItemBase.TYPE_PAGE_TITLE==t) {
            objNm+="[页标题]";
        } else if(SJGReplaceItemBase.TYPE_PAGE_SUBTITLE==t) {
            objNm+="[页副标题]";
        }

        if(selPage.isPageComment(this.id)) {
            objNm+="[页备注]";
        }
        
        return objNm;
    }
    //--------------------------------计算数据 start------------------------------------------
    // 计算数据：重置各字符bx、by，以及各段高宽
    public refresh(replace: SJGReplaceGroup=null) {
        super.refresh();
        
        // 计算正文
        this.refreshMainText();
        
        // 计算小标题
        this.refreshTitle();
        
        // 计算抬头
        this.refreshHead();


        this.refreshHead2();// 2017-07,此行功能供非APP的模版的抬头使用
            
    }
    // 计算小标题
    private refreshTitle(){
        if(!this.title) return;
        // 计算小标题文字
        this.title.refresh();
        // 计算小标题位置
        var a: ObjPosition=this.pos.clone();
        a.x=0; a.y=0;
        var newPos: ObjPosition=ObjRelativePosType.calPostionOfRelative(a,this.title.pos,this.titlePos,this.titleOffset);
        this.title.pos=newPos;
    }
    // 抬头对齐到小标题上
    private refreshHeadToTitle(){
        // 计算出head相对于title的偏移［坐标系为TextExObj的左上角］
        var a: ObjPosition=this.title.pos.clone();
        var newPos: ObjPosition=ObjRelativePosType.calPostionOfRelative(a,this.head.pos,this.headPos,this.headOffset);
        
        // 设置抬头新位置
        this.head.pos=newPos;
    }
    // 抬头对齐到正文
    private refreshHeadToText() {
        // 计算出head相对于TextExtObj的偏移［坐标系为TextExObj的左上角］
        var a: ObjPosition=this.pos.clone();
        a.x=0; a.y=0;
        var newPos: ObjPosition=ObjRelativePosType.calPostionOfRelative(a,this.head.pos,this.headPos,this.headOffset);
        // 设置抬头新位置
        this.head.pos=newPos;
    }
    // 抬头对齐到正文和小标题的整体
    private refreshHeadToTitleAndText() {
        if(this.title) {
            // 计算出小标题和正文的区域［坐标系为TextExObj的左上角］
            var a_text: ObjPosition=this.pos.clone();
            a_text.x=0; a_text.y=0;
            var a: ObjPosition=this.title.pos.clone();
            a.union(a_text);// 合并小标题和正文
            var a_all: ObjPosition=a.clone();
            // 计算出head的区域［坐标系为TextExObj的左上角］
            var newPos: ObjPosition=ObjRelativePosType.calPostionOfRelative(a,this.head.pos,this.headPos,this.headOffset);
           
            // 设置抬头新位置
            this.head.pos=newPos;
        }
    }
    // 计算抬头
    private refreshHead() {
        if(!this.head) return;
        // 计算抬头文字
        this.head.refresh();
        // 计算抬头位置
        if(this.headAlignTo==TextExtObj.HEAD_ALIGN_TO_TITLE){
            if(this.title){
                this.refreshHeadToTitle();
            }else{
                this.refreshHeadToText();
            }
        } else if(this.headAlignTo==TextExtObj.HEAD_ALIGN_TO_TEXT) {
            this.refreshHeadToText();

        } else if(this.headAlignTo==TextExtObj.HEAD_ALIGN_TO_TITLE_AND_TEXT) {
            if(this.title) {
                this.refreshHeadToTitleAndText();    
            }else{
                this.refreshHeadToText();    
            }
        }

    }
    // 计算正文
    private refreshMainText(){
        var minus: number=this.refreshAlignLeft();
        this.refreshToAlignType();
        this.refreshToVerticleAlignType(minus);
    }
    
    // 按左对齐排列
    // 返回：文字的高与文字轮廓的高的差值
    public static Y_FACTOR: number=4/5;
    private refreshAlignLeft(): number {
        if(this.pc == null) {
            return;
        }

        var X_HEAD_WIDTH=this.txtStPt.x||TextObj.HEAD_WIDTH;// 2017-07

        // 遍历轮廓中的每个字，从左向右放，直到碰到this.pos.w为止
        var lineH: number=this.style.fs;
        var lineW: number=this.pos.w;
        var line: number=0; // 行数
        var curX: number=X_HEAD_WIDTH
        for(var i in this.pc.paras) {
            if(i>0) {// 新段落新起一行
                line++;
                curX=X_HEAD_WIDTH
            }

            var onePara: OnePara=this.pc.paras[i];
            for(var j in onePara.chars) {
                var oneChar: ParaChar=onePara.chars[j];
                // 如果超出边界，新起一行
                curX+=oneChar.w/this.fz;
                if(curX>(lineW-TextObj.TAIL_WIDTH)&&(i>0||j>0)) {
                    line++;
                    curX=X_HEAD_WIDTH+oneChar.w/this.fz;
                }
                oneChar.bx=curX-oneChar.w/this.fz;
                oneChar.by=lineH*(line+TextObj.Y_FACTOR)+this.style.ls*(line+1);
                oneChar.line=line;

                // 加上字间距
                curX+=this.style.cs;
            }
        }
        // 只有新的高度大于旧的高度时，才更新
        var newH: number=(line+1)*lineH+(line+1)*this.style.ls;
        var oldH: number=this.pos.h
        if(newH>this.pos.h) {
            this.pos.h=newH;
        }

        return oldH-newH;
    }
    // 垂直方向调整为正确的排列方式
    private refreshToVerticleAlignType(minus) {
        if(minus<=0) return;

        var vOffset: number=0;
        if(this.style.vpo==TextObj.V_POSITION_CENTER) {
            vOffset=minus/2;
        } else if(this.style.vpo==TextObj.V_POSITION_BOTTOM) {
            vOffset=minus;
        }

        if(vOffset>0) {
            for(var i in this.pc.paras) {
                var onePara: OnePara=this.pc.paras[this.pc.paras.length-1-i];// 倒着遍历
                for(var j in onePara.chars) {
                    var oneChar: ParaChar=onePara.chars[onePara.chars.length-1-j];// 倒着遍历
                    oneChar.by+=vOffset;
                }
            }
        }
    }
    // 水平方向调整为正确的排列方式
    private refreshToAlignType() {
        var line: number=-1;
        var offset: number=0;// line对应的偏移
        if(this.style.po==TextObj.POSITION_RIGHT
            ||this.style.po==TextObj.POSITION_CENTER) {
            for(var i in this.pc.paras) {
                var onePara: OnePara=this.pc.paras[this.pc.paras.length-1-i];// 倒着遍历
                if(onePara.chars.length==0) {// 空行
                    if(line>0) {
                        line=line-1;
                    } else {
                        line=-1;
                    }
                    continue;
                }

                for(var j in onePara.chars) {
                    var oneChar: ParaChar=onePara.chars[onePara.chars.length-1-j];// 倒着遍历
                    var rightest: Boolean=false;// 一行的最右侧
                    if(line==-1) {// 最后一个字
                        rightest=true;
                    } else if(oneChar.line==(line-1)) { // 换行时
                        rightest=true;
                    }
                    if(rightest) {
                        line=oneChar.line;
                        offset=this.pos.w-TextObj.TAIL_WIDTH-oneChar.w/this.fz-oneChar.bx;
                        if(this.style.po==TextObj.POSITION_CENTER) {// 居中对齐的偏移减半
                            offset=offset/2;
                        }
                    }
                    // 调整
                    oneChar.bx+=offset;
                }
            }
        }
    }
    //--------------------------------计算数据 end------------------------------------------
    
    // 扩展大小
    // 参数：controlType 控制点类型
    // 参数：ratioX x缩放比例
    // 参数：ratioY y缩放比例
    // 参数：outside true表示操作所在的最外层对象，false表示内部对象
    public expand(controlType: number,ratioX: number,ratioY: number,outside: boolean) {
        super.expand(controlType,ratioX,ratioY,outside);

//        if(SJGSelectRect.CONTROL_LEFT==controlType
//            ||SJGSelectRect.CONTROL_RIGHT==controlType) { 
//        if(this.constrain.scale==1) {
            this.refresh();
//        }
//        }
        
    }
    
    
    
    // 缩放对象
    public scale(s: number) {
        super.scale(s);
        
        if(this.title){
            this.title.scale(s);
        }
    }
    
    
    
    
    // 添加子对象，能够添加子对象的对象重载
    // 参数：child 待添加的字对象
    // 参数：insertIndex 待添加的位置
    // 参数：flag 操作flag， flag==1 表示添加为文字抬头, flag==2 表示添加为文字小标题
    public addChild(child: ObjBase,insertIndex: number,flag: number=0): boolean {
        if(flag==1) {
            super.addChild(child,insertIndex,flag);
        }else if(flag==2){
            this.removeChild(child.id);
            this.title=child;
            child.parent=this;
        }
        
        return true;
    }
    // 删除子对象，能够添加子对象的对象重载
    public removeChild(id: number) {
        super.removeChild(id);
        
        if(this.title&&this.title.id==id){
            this.title.parent=null;
            this.title=null;
        }
    }
    
    // 深度更新id［处理自身和子对象，递归］
    // 参数：idMaps，新旧id的对应关系, 例如：[{oldId:1,newId:2}]
    public deepResetId(idMaps: Array<any>) {
        super.deepResetId(idMaps);
        
        if(this.title){
            this.title.deepResetId(idMaps);
        }
    }
    // 从json对象(注意不是json字符串)中解析出ObjBase的信息
    public baseInfoFromJson(jsonObj,versionId,keepCt=true) {
        if(keepCt) {
            var oldCt=this.ct;
            super.fromJson(jsonObj,versionId);
            this.ct=oldCt;
        } else {
            super.fromJson(jsonObj,versionId);
        }
    }
    //  旧文字转心文字
    public static fromTextObj(old:TextObj,g?):TextExtObj{
        var ret: TextExtObj=new TextExtObj(g);
        ret.baseInfoFromJson(old,0);
        
        ret.te=old.te;
        ret.fz=old.fz;
        ret.style.fn=old.fn;
        ret.style.fs=old.fs;
        ret.style.bi=old.bi;
        ret.style.po=old.po;
        ret.style.vpo=old.vpo;
        ret.style.cs=old.cs;
        ret.style.ls=old.ls;
        ret.style.td=old.td;
        ret.style.min=old.min;
        ret.style.max=old.max;
        ret.style.al=old.al;
        ret.style.color=old.color.copy();
        ret.pc=old.pc.copy();
        if(old.head){
            ret.head=old.head;
            ret.head.parent=ret;
            if(old.hp==TextObj.HP_LEFT){
                ret.headPos=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_1,ObjPositionAlign.ALIGN_POINT_7);
                ret.headOffset=new Point(-old.hd,0);
                ret.headAlignTo=TextExtObj.HEAD_ALIGN_TO_TEXT;
            } else if(old.hp==TextObj.HP_TOP) {
                ret.headPos=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_5,ObjPositionAlign.ALIGN_POINT_7);
                ret.headOffset=new Point(0,-old.hd);
                ret.headAlignTo=TextExtObj.HEAD_ALIGN_TO_TEXT;
            } else if(old.hp==TextObj.HP_RIGHT) {
                ret.headPos=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_7,ObjPositionAlign.ALIGN_POINT_1);
                ret.headOffset=new Point(old.hd,0);
                ret.headAlignTo=TextExtObj.HEAD_ALIGN_TO_TEXT;
            } else if(old.hp==TextObj.HP_BOTTOM) {
                ret.headPos=new ObjRelativePosType(ObjPositionAlign.ALIGN_POINT_7,ObjPositionAlign.ALIGN_POINT_5);
                ret.headOffset=new Point(0,old.hd);
                ret.headAlignTo=TextExtObj.HEAD_ALIGN_TO_TEXT;
            } 
            
            // 还原ret的位置与正文左上角对齐
            ret.head.pos.x=0;
            ret.head.pos.y=0;
            
            // 根据参数重新计算
            ret.refresh();
        }
        
        
        
        
        return ret;
    }
    // 将旧的title添加为新的title
    public addTitleFromOld(old:TextObj){
        if(old) {
            // 根据旧文字创建新文字，保持id不变
            var newTitle: TextExtObj=TextExtObj.fromTextObj(old, this.getGlobalData());
            newTitle.tt=TextExtObj.TEXT_TYPE_TITLE;
            // 更新对象管理器
            this.getGlobalData().objManager().saveObject(newTitle);
            // 建立对父的引用
            newTitle.parent=this;
            
            // 根据old跟this的相对位置决定titlePos和titleOffset
            var r:any = ObjRelativePosType.calcRelativePosType(newTitle.pos,this.pos);
            this.title=newTitle;
            this.titlePos=r.type;
            this.titleOffset=r.offset;
            
            // 还原title的位置与正文左上角对齐
            this.title.pos.x=0;
            this.title.pos.y=0;
            
            // 根据参数重新计算
            this.refresh();
        }        
    }
    
    
    // 将文字排到一行上，并且限定宽度，如果超过宽度，则缩放文字
    public refreshToOneLineAndFixWidth() {
        var newLen=this.refreshToOneLine();
        var ratio: number=this.pos.w/newLen;
        if(ratio<1.0) {
            // 缩放字号、字间距、行间距
            this.style.fs*=ratio;
            this.style.cs*=ratio;
            this.style.ls*=ratio;
            // 缩放每个字的轮廓
            this.pc.adjustPosition(ratio,ratio,2);
        }
        
        // 刷新水平对齐和垂直对齐方式
        this.refreshToAlignType();
        this.refreshToVerticleAlignType(0);

        
    }
    // 将文字排到一行上
    private refreshToOneLine() {
        // 遍历轮廓中的每个字，从左向右放
        var lineH: number=this.style.fs;
        var lineW: number=this.pos.w;

        var curX: number=TextObj.HEAD_WIDTH;
        for(var i in this.pc.paras) {

            var onePara: OnePara=this.pc.paras[i];
            for(var j in onePara.chars) {
                var oneChar: ParaChar=onePara.chars[j];
                // 如果超出边界，新起一行
                curX+=oneChar.w/this.fz;
                oneChar.bx=curX-oneChar.w/this.fz;
                oneChar.by=lineH*(TextObj.Y_FACTOR)+this.style.ls;
                oneChar.line=0;
                
                // 加上字间距
                curX+=this.style.cs;
            }
        }
        
        
        // 更新高度
        var newH: number=lineH+2*this.style.ls;
        var oldH: number=this.pos.h
        this.pos.h=newH;

        return curX;
    }

    // 计算半角长度
    public static getLengthInBytes(str) {
        var b = str.match(/[^\x00-\xff]/g);
        return (str.length + (!b ? 0: b.length));
    }

    // 计算全角长度
    public static getLengthInDoubleBytes(str){
        return TextExtObj.getLengthInBytes(str)/2;
    }




//SJG_MARK_APPEND--------------------

    // 减小字号将文字限制到boundingBox上
    public setTextToBoundingBox(str:string, max:number) {
        this.te = str;
        if(!str){
            return;
        }

        // 否则，计算新字号
        var MIN_FS = 1;
        var MAX_FS = this.style.fs;
        var s = this.style.fs;
        if(str.indexOf('\n')>=0){
            console.log('find \\n, origin fs is:'+this.style.fs+',w is:'+this.pos.w+',h is:'+this.pos.h);
            // 如果字符串有换行
            var ret = this.tryFontSize(MIN_FS,MAX_FS);
            console.log('tryFontSize('+MIN_FS+','+MAX_FS+')-------- '+ret);
            if(ret){
                s = ret;
            }
        }else{
            console.log('no \\n, origin fs is:'+this.style.fs+',w is:'+this.pos.w+',h is:'+this.pos.h);
            // 如果字符串没有换行
            // 计算文本框能放下的行列数
            var _w=Math.floor(this.pos.w/(this.style.fs+this.style.cs));
            _w=_w>=1?_w:1;
            var _h=Math.floor(this.pos.h/(this.style.fs+this.style.ls));
            _h=_h>=1? _h:1;

            // 如果str长度小于原先长度，则直接刷新
            var len = Math.floor(TextExtObj.getLengthInDoubleBytes(str));
            if(len<=_w*_h) {
                return;
            }
            // 如果“设计”中是一行，则新生成的数据只能是一行
            if(_h==1){
                var ret = this.tryScaleToOneLine(len);
                console.log('tryScaleToOneLine('+MIN_FS+','+MAX_FS+')-------- '+ret);
                if(ret){
                    s = ret;
                }
            }else{
                // 如果“设计”中是多行，则生成结果不受限制
                var ret = this.tryFontSize(MIN_FS,MAX_FS);
                console.log('tryFontSize('+MIN_FS+','+MAX_FS+')-------- '+ret);
                if(ret){
                    s = ret;
                }
            }
        }

        // 根据行数，计算字号
        this.style.fs = s;

        // 将文字垂直居中
        this.style.vpo = TextObj.V_POSITION_CENTER;
    }

    // 缩放字号，将文字显示在一
    public tryScaleToOneLine(doubByteLen:number):number {
        console.log('-----tryScaleToOneLine:' + doubByteLen+', w is:'+this.pos.w);
        var fs = this.pos.w/doubByteLen-this.style.cs;
        var fs = fs<this.pos.h?fs:this.pos.h;
        fs = Math.ceil(fs);

        return fs;
    }


    // 挨个试验字号,二分法
    public tryFontSize(min:number,max:number):number{
        console.log('-----tryFontSize:'+min+','+max);
        if(max<=min)    return null;

        var minOk = this.isFontSizeOk(min);
        var maxOk = this.isFontSizeOk(max);
        if(minOk && maxOk){
            return max;
        }else if(!minOk && maxOk){
            if(min>=(max-1))    return max;

            // 缩小查找范围：min增加一半，max减小一
            var middle = Math.floor((min+max)/2);
            var middleOk = this.isFontSizeOk(middle);
            if(middleOk){
                // 向前找
                var newMin = min+1;
                var newMax = middle-1;
                var ret = this.tryFontSize(newMin,newMax);
                if(!ret){
                    return middle;
                }else{
                    return ret;
                }
            }else{
                // 向后找
                var newMin = middle+1;
                var newMax = max-1;
                var ret = this.tryFontSize(newMin,newMax);
                if(!ret){
                    return max;
                }else{
                    return ret;
                }

            }
        }else if(minOk && !maxOk){
            if(min>=(max-1))    return min;

            // 缩小查找范围：min增加一，max减小一半
            var middle = Math.ceil((min+max)/2);
            var middleOk = this.isFontSizeOk(middle);
            if(middleOk){
                // 向后找
                var newMin = middle+1;
                var newMax = max-1;
                var ret = this.tryFontSize(newMin,newMax);
                if(!ret){
                    return middle;
                }else{
                    return ret;
                }

            }else{
                // 向前找
                var newMin = min+1;
                var newMax = middle-1;
                var ret = this.tryFontSize(newMin,newMax);
                if(!ret){
                    return min;
                }else{
                    return ret;
                }
            }
        }else{
            return null;
        }
    }
    // 某个字号是否符合要求
    public isFontSizeOk(fs):boolean{
        var orcc = this.oneRowCharCount(fs);
        var arr = this.te.split('\n');
        var curX=0,curY=0;
        for(var i=0;i<arr.length;i++){
            var para = arr[i];
            var paraLen = TextExtObj.getLengthInDoubleBytes(para);
            var paraRow = Math.ceil(paraLen/orcc);
            curY +=(paraRow*(fs+this.style.ls));
        }
        return curY<=this.pos.h;
    }
    // 某个字号下，一行能放的字数
    public oneRowCharCount(fs):number{
        var max =Math.floor(this.pos.w/fs);//上限
        var min = Math.floor(this.pos.w/(fs+this.style.cs));//下限
        var ret = min;
        for(var i=max-1;i>=min;i--){
            if(i*fs+(i-1)*this.style.cs <=this.pos.w){
                ret = i;
                break;
            }
        }

        return ret;

    }

    //////////////////////////////////////////////////////////////////////////////////////////
    private refreshHead2(){

        if(this.head && this.headStyle) {
            this.head.refresh();

            // 取当前文字轮廓起始位置(左上角)
            var lastY=this.pos.y+this.pos.h;
            if(this.pc && this.pc.paras.length>0 && this.pc.paras[0].chars.length>0) {
                this.txtStPt.x=this.pc.paras[0].chars[0].bx;
                this.txtStPt.y=this.pc.paras[0].chars[0].by-this.style.fs*0.8;

                var lastPara=this.pc.paras[this.pc.paras.length-1];
                var lastChar=lastPara.chars[lastPara.chars.length-1];
                lastY=lastChar.by+this.style.fs*0.2;

            } else {
                this.txtStPt.x=0;
                this.txtStPt.y=0;
            }

            // 计算文字轮廓区域
            var txtPos: ObjPosition=new ObjPosition();
            txtPos.x=this.txtStPt.x;
            txtPos.y=this.txtStPt.y;
            txtPos.w=this.pos.w-this.txtStPt.x;
            txtPos.h=lastY-this.txtStPt.y;

            // TODO: 根据偏移倍数重新计算偏移量
            //this.headStyle.headOffset.x=this.style.fs*Number(this.headStyle.offsetRatioX||'0');
            //this.headStyle.headOffset.y=this.style.fs*Number(this.headStyle.offsetRatioY||'0');

            // 根据当前文字轮廓区域计算抬头新的位置
            var newPos: ObjPosition=ObjRelativePosType.calPostionOfRelative(txtPos,this.head.pos,
                this.headStyle.headPos,this.headStyle.headOffset);
            // 偏移修正
            if(this.headStyle.headPos.is_1_7()) {
                // 对齐到首行文字中间
                newPos.y=newPos.y+(this.style.fs-this.head.pos.h)/2;

            } else if(this.headStyle.headPos.is_2_6()) {
                // 对齐到所有文字中间
                // 不用修证

            } else if(this.headStyle.headPos.is_3_5()) {
                // 对齐到尾行文字中间
                newPos.y=newPos.y-(this.style.fs-this.head.pos.h)/2;

            } else {
                // TODO
            }

            // 新的文字对象原点偏移量
            var newOrgOffset: Point=new Point(txtPos.x,0);
            if(newPos.x<txtPos.x) {
                newOrgOffset.x=newPos.x;
            }

            // 坐标转换: 文字对象位置尺寸
            this.pos.x=this.pos.x+newOrgOffset.x;
            //this.pos.y=this.pos.y+newOrgOffset.y;
            this.pos.w=this.pos.w-newOrgOffset.x;
            //this.pos.h=this.pos.h-newOrgOffset.y;
            // 坐标转换: 抬头位置
            this.head.pos.x=newPos.x-newOrgOffset.x;
            this.head.pos.y=newPos.y-newOrgOffset.y;
            // 坐标转换: 文字轮廓起始位置
            this.txtStPt.x=this.txtStPt.x-newOrgOffset.x;
            this.txtStPt.y=this.txtStPt.y-newOrgOffset.y;

            // 坐标转换: 文字轮廓bx,by
            if(this.pc&&this.pc.paras.length>0&&this.pc.paras[0].chars.length>0) {
                for(var i=0;i<this.pc.paras.length;i++) {
                    var para=this.pc.paras[i];
                    for(var j=0;j<para.chars.length;j++) {
                        var char=para.chars[j];
                        char.bx=char.bx-newOrgOffset.x;
                        char.by=char.by-newOrgOffset.y;
                    }
                }
            }

            // 宽度限制
            var minW=(this.txtStPt.x>0)? (this.txtStPt.x+this.style.fs): this.style.fs;
            if(this.pos.w<minW) {
                this.pos.w=minW;// 一个字宽+起始偏移
            }

        } else {// 没有抬头或删除抬头

            // 新的文字对象原点偏移量
            var newOrgOffset: Point=new Point(this.txtStPt.x,0);// TODO 暂未考虑y方向

            // 坐标转换: 文字对象位置尺寸
            this.pos.x=this.pos.x+newOrgOffset.x;
            //this.pos.y=this.pos.y+newOrgOffset.y;
            this.pos.w=this.pos.w-newOrgOffset.x;
            //this.pos.h=this.pos.h-newOrgOffset.y;
            // 坐标转换: 抬头位置
            if(this.head) {
                this.head.pos.x=newPos.x-newOrgOffset.x;
                this.head.pos.y=newPos.y-newOrgOffset.y;
            }
            // 坐标转换: 文字轮廓起始位置
            this.txtStPt.x=this.txtStPt.x-newOrgOffset.x;
            this.txtStPt.y=this.txtStPt.y-newOrgOffset.y;

            // 坐标转换: 文字轮廓bx,by
            if(this.pc&&this.pc.paras.length>0&&this.pc.paras[0].chars.length>0) {
                for(var i=0;i<this.pc.paras.length;i++) {
                    var para=this.pc.paras[i];
                    for(var j=0;j<para.chars.length;j++) {
                        var char=para.chars[j];
                        char.bx=char.bx-newOrgOffset.x;
                        char.by=char.by-newOrgOffset.y;
                    }
                }
            }

            // 宽度限制
            var minW=this.style.fs;
            if(this.pos.w<minW) {
                this.pos.w=minW;// 一个字宽
            }
        }
    }

}//SJG_MARK_END-------------------------